home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume90 / devices / env2manx.0 / funcs.c < prev    next >
C/C++ Source or Header  |  1990-01-29  |  16KB  |  779 lines

  1. /*
  2.  *  FILE
  3.  *    funcs.c
  4.  *
  5.  *  DESCRIPTION
  6.  *    All the functions for actually read and write the MANX
  7.  *    environment variables.
  8.  *
  9.  *  AUHOR
  10.  *    Anders `ALi' Lindgren
  11.  *    Marlarblick 8
  12.  *    S-161 51 Bromma
  13.  *    Sweden
  14.  *
  15.  *  STATUS
  16.  *    This file is in the Public Domain.
  17.  *
  18.  *  CODE HISTORY
  19.  *    26-Sep-89   (10:51) Created this file.
  20.  *    27-Sep-89   (18:56) Read works ok.
  21.  *            (19:27) ReAlloc written.
  22.  *            (12:00) Both Read and Write works ok.
  23.  *    28-Sep-89   (14:00) Locks implemented.
  24.  *
  25.  *     1-Oct-89        No hacking. I was employed by Commodore,
  26.  *       ...            Sweden at the Alvsjo copmuter fair.
  27.  *     6-Oct-89
  28.  *     6-Oct-89        (Gee, today I bougth a 2000 :-) )
  29.  *
  30.  *     6-Oct-89   (23:30) Implemented Directory functions. Some
  31.  *                people wanted it badly.
  32.  *     8-Oct-89   (12:00) Directory functions works ok.
  33.  *
  34.  *       ...            (I got my hands on MicroGNUEmacs 3. It`s GREAT!)
  35.  *
  36.  *    17-Oct-89        I threw out the old directory functions, becauce
  37.  *                they didn`t function the way I liked. 
  38.  *
  39.  *    20-Jan-90        I`m sorry, but I have been up to my neck into
  40.  *                other things so I haven`t been able to work
  41.  *                on the project. Well, now it`s released, enjoy!
  42.  *
  43.  *  DISCUSSION
  44.  *    Change __builtin_memcpy to CopyMem???
  45.  */
  46.  
  47. #include "funcs.h"
  48.  
  49. /*
  50.  *  FUNCTION
  51.  *    action_input
  52.  *
  53.  *  DESCRIPTION
  54.  *    Read an MANX variable. This function copies the variable
  55.  *    value to a temporary buffer.
  56.  *
  57.  *    The valuebuf structure conatisn the following fields:
  58.  *        vb_buf - Pointer to the temporary buffer.
  59.  *        vb_pos - Index, pointing to the next char to be read.
  60.  *        vb_end - Size of the Buffer.
  61.  *
  62.  *    When vb_pos and vb_end is equal, all data was been read.
  63.  */
  64.  
  65. void
  66. action_input (register struct DosPacket * pkt, struct MsgPort * port)
  67. {
  68.     register struct FileHandle * fh;
  69.     register struct valuebuf   * vb;
  70.     register        char       * var;
  71.     register        int      len;
  72.             char     name[NAMESIZE];
  73.             char       * varname;
  74.  
  75.     pkt->dp_Res1 = DOS_FALSE;
  76.  
  77.     fh = (struct FileHandle *)BTOC(pkt->dp_Arg1);
  78.  
  79.     BtoCStr(name, pkt->dp_Arg3, NAMESIZE-1);
  80.     varname = BaseName ( name );
  81.  
  82.     if ( * varname ) {
  83.  
  84.     Forbid();
  85.  
  86.     if (var = mygetenv(varname)) {
  87.  
  88.         if (vb = (struct valuebuf *) AllocMem( sizeof(struct valuebuf),
  89.                     MEMF_PUBLIC | MEMF_CLEAR ) ) {
  90.  
  91.         fh->fh_Type  = port;
  92.         fh->fh_Arg1  = (long) vb;
  93.  
  94.         len = __builtin_strlen(var);
  95.  
  96.         if (vb->vb_buf = AllocMem(len, MEMF_PUBLIC | MEMF_CLEAR)) {
  97.             vb->vb_end = len;
  98.             vb->vb_pos = 0;
  99.  
  100.             __builtin_memcpy(vb->vb_buf, var, len);
  101.  
  102.             vb->vb_flags = ENVF_READ;
  103.  
  104.             pkt->dp_Res1 = DOS_TRUE;
  105.         }
  106.         else {
  107.             pkt->dp_Res2 = ERROR_NO_FREE_STORE;
  108.             FreeMem((char *)vb, sizeof(struct valuebuf));
  109.         }
  110.         }
  111.         else {
  112.         pkt->dp_Res2 = ERROR_NO_FREE_STORE;
  113.         }
  114.     }
  115.     else {
  116.         pkt->dp_Res2 = ERROR_OBJECT_NOT_FOUND;
  117.     }
  118.  
  119.     Permit();
  120.     }
  121.     else {
  122.     pkt->dp_Res2 = ERROR_BAD_STREAM_NAME;
  123.     }
  124.  
  125.     return;
  126. }
  127.  
  128.  
  129. /*
  130.  *  FUNCTION
  131.  *    action_read
  132.  *
  133.  *  DESCRIPTION
  134.  *    Writes the buffer to the fh.
  135.  */
  136.  
  137. void
  138. action_read (register struct DosPacket * pkt)
  139. {
  140.     register struct valuebuf * vb;
  141.     register        int        num;
  142.  
  143.     vb = (struct valuebuf *)pkt->dp_Arg1;
  144.  
  145.     if (vb->vb_flags & ENVF_READ) {
  146.  
  147.             /* Already read all? */
  148.     if (vb->vb_pos == vb->vb_end) {
  149.         pkt->dp_Res1 = 0;
  150.     }
  151.         else {
  152.         /* Get the smallest, buffer or remaining chars */
  153.         if ( (vb->vb_end - vb->vb_pos) <= pkt->dp_Arg3 ) {
  154.             num = vb->vb_end - vb->vb_pos;
  155.         }
  156.         else {
  157.         num = pkt->dp_Arg3;
  158.         }
  159.  
  160.         __builtin_memcpy( (void *)pkt->dp_Arg2,
  161.                 (void *)(vb->vb_buf + vb->vb_pos), num );
  162.  
  163.         vb->vb_pos += num;
  164.  
  165.         pkt->dp_Res1 = num;
  166.     }
  167.     }
  168.     else {
  169.     pkt->dp_Res1 = 0;
  170.     pkt->dp_Res2 = ERROR_OBJECT_WRONG_TYPE;
  171.     }
  172.     return;
  173. }
  174.  
  175.  
  176. /*
  177.  *  FUNCTION
  178.  *    action_output
  179.  *
  180.  *  DESCRIPTION
  181.  *    Open the env: for writing a variable.
  182.  *    This function allocates memory for the namestring.
  183.  *    It doesn`t allocate memory for the buffer, because if the
  184.  *    vb_buf is zero (ie. no write has been made) the Setenv
  185.  *    function removes the variable.
  186.  */
  187.  
  188. void
  189. action_output (register struct DosPacket * pkt, struct MsgPort * port)
  190. {
  191.     register struct valuebuf   * vb;
  192.     register        char       * varname;
  193.     register        int         namelen;
  194.          struct FileHandle * fh;
  195.             char     name[NAMESIZE];
  196.  
  197.     pkt->dp_Res1 = DOS_FALSE;
  198.  
  199.     if (vb = (struct valuebuf *) AllocMem( sizeof(struct valuebuf),
  200.                         MEMF_PUBLIC | MEMF_CLEAR ) ) {
  201.  
  202.     fh = (struct FileHandle *)BTOC(pkt->dp_Arg1);
  203.  
  204.     BtoCStr(name, pkt->dp_Arg3, NAMESIZE-1);
  205.     varname = BaseName( name );
  206.  
  207.     if ( * varname ) {
  208.         namelen = __builtin_strlen(varname) + 1;
  209.  
  210.         if (vb->vb_name = DosAllocMem(namelen)) {
  211.         __builtin_memcpy(vb->vb_name, varname, namelen);
  212.  
  213.         fh->fh_Type  = port;
  214.         fh->fh_Arg1  = (long) vb;
  215.  
  216.         vb->vb_flags = ENVF_WRITE;
  217.  
  218.         pkt->dp_Res1 = DOS_TRUE;
  219.         return;             /* Correct exit */
  220.         }
  221.                 /* Error hancdling code */
  222.         else {
  223.         pkt->dp_Res2 = ERROR_NO_FREE_STORE;
  224.         }
  225.     }
  226.     else {
  227.         pkt->dp_Res2 = ERROR_BAD_STREAM_NAME;
  228.     }
  229.     FreeMem((char *)vb, sizeof(struct valuebuf));
  230.     }
  231.     else {
  232.     pkt->dp_Res2 = ERROR_NO_FREE_STORE;
  233.     }
  234.     return;    /* Error Exit! */
  235. }
  236.  
  237.  
  238. /*
  239.  *  FUNCTION
  240.  *    action_write
  241.  *
  242.  *  DESCRIPTON
  243.  *    Called when a client writes the contents of a environment
  244.  *    variable.
  245.  *    The data is stored at at buffer. If the buffer is smaler
  246.  *    than the data, the buffer is expanded.
  247.  *    BUFSIZE is the amount of extra memory which shall be
  248.  *    allocated at a ReAlloc call.
  249.  *    (If BUFSIZE is zero, a ReAlloc call will be made at
  250.  *    every write.)
  251.  *
  252.  *  NOTE
  253.  *    No errorchecking is made on the ReAlloc function, yet....
  254.  */
  255.  
  256. void
  257. action_write (register struct DosPacket * pkt)
  258. {
  259.     register struct valuebuf    * vb;
  260.     register char        * newbuf;
  261.  
  262.     vb = (struct valuebuf *)pkt->dp_Arg1;
  263.  
  264.     if (vb->vb_flags & ENVF_WRITE) {
  265.  
  266.     if (vb->vb_pos + pkt->dp_Arg3 + 1 >= vb->vb_end) {
  267.         newbuf = ReAlloc(vb->vb_buf, vb->vb_end,
  268.             vb->vb_end + pkt->dp_Arg3 + BUFSTEP, MEMF_CLEAR);
  269.         if (newbuf == NULL) {
  270.         FreeMem (vb->vb_buf, vb->vb_end);
  271.         DosFreeMem (vb->vb_name);
  272.         FreeMem ((char *)vb, sizeof(struct valuebuf));
  273.         pkt->dp_Res1 = 0;
  274.         pkt->dp_Res2 = ERROR_NO_FREE_STORE;
  275.         return;
  276.         }
  277.         vb->vb_buf = newbuf;
  278.         vb->vb_end += pkt->dp_Arg3 + BUFSTEP;
  279.     }
  280.     __builtin_memcpy(vb->vb_buf + vb->vb_pos, (void *)pkt->dp_Arg2,
  281.                             pkt->dp_Arg3);
  282.     vb->vb_pos += pkt->dp_Arg3;
  283.  
  284.     pkt->dp_Res1 = pkt->dp_Arg3;
  285.     }
  286.     else {
  287.     pkt->dp_Res1 = 0;
  288.     pkt->dp_Res2 = ERROR_OBJECT_WRONG_TYPE;
  289.     }
  290.     return;
  291. }
  292.  
  293.  
  294. /*
  295.  *  FUNCTION
  296.  *    action_end
  297.  *
  298.  *  DESCRIPTION
  299.  *    This function is executed when someone Close()`s the filehandler.
  300.  *
  301.  *    On read, it simply frees the memory. On Write, the actual
  302.  *    writing takes place here.
  303.  */
  304.  
  305. void
  306. action_end (register struct DosPacket * pkt)
  307. {
  308.     register struct valuebuf * vb;
  309.  
  310.     pkt->dp_Res1 = DOS_FALSE;
  311.  
  312.     if (vb = (struct valuebuf *)pkt->dp_Arg1) {
  313.  
  314.     if (vb->vb_flags & ENVF_READ) {
  315.         if (vb->vb_buf && vb->vb_end) {
  316.         FreeMem( (char *)vb->vb_buf, vb->vb_end);
  317.         FreeMem( (char *)vb, sizeof(struct valuebuf) );
  318.         }
  319.         pkt->dp_Res1 = DOS_TRUE;
  320.     }
  321.     else if (vb->vb_flags & ENVF_WRITE) {
  322.         if (vb->vb_name) {
  323.         Setenv(vb->vb_name, vb->vb_buf);
  324.         DosFreeMem(vb->vb_name);
  325.         }
  326.         if (vb->vb_buf) {
  327.         FreeMem(vb->vb_buf, vb->vb_end);
  328.         }
  329.         FreeMem((char *)vb, sizeof(struct valuebuf));
  330.  
  331.         pkt->dp_Res1 = DOS_TRUE;
  332.     }
  333.     else {    /* Error */
  334.         pkt->dp_Res2 = ERROR_OBJECT_WRONG_TYPE;
  335.     }
  336.     }
  337.     else {
  338.     pkt->dp_Res2 = ERROR_OBJECT_WRONG_TYPE;
  339.     }
  340.     return;
  341. }
  342.  
  343.  
  344. /*
  345.  *  FUNCTION
  346.  *    action_lock
  347.  *
  348.  *  DESCRIPTION
  349.  *    Lock the env: device, or a `file'.  If a file is locked, the filename
  350.  *    is copied to a aread pointed to by lock->fl_Name.
  351.  *
  352.  *  ARGUMENTS
  353.  *    Arg1 : Lock
  354.  *    Arg2 : Name
  355.  *    Arg3 : Mode
  356.  */
  357.  
  358. void
  359. action_lock (register struct DosPacket * pkt,
  360.               struct MsgPort   * port,
  361.               struct DosList   * node)
  362. {
  363.     register struct myFileLock  * lock;
  364.             char      name[NAMESIZE];
  365.             char    * namebase;
  366.  
  367.     pkt->dp_Res1 = NULL;
  368.  
  369.     if (lock = (struct myFileLock *)AllocMem(sizeof(struct myFileLock),
  370.                         MEMF_PUBLIC | MEMF_CLEAR)) {
  371.     pkt->dp_Res1 = CTOB(lock);
  372.  
  373.     lock->fl_Access = pkt->dp_Arg3;
  374.     lock->fl_Task   = port;
  375.     lock->fl_Volume = CTOB(node);
  376.  
  377.     BtoCStr(name, pkt->dp_Arg2, NAMESIZE-1);
  378.     if (* (namebase = BaseName( name ))) {
  379.         if ( (lock->fl_Name = getenvname( namebase )) == NULL ) {
  380.         FreeMem ((char *)lock, sizeof(struct myFileLock));
  381.         pkt->dp_Res1 = NULL;
  382.         pkt->dp_Res2 = ERROR_OBJECT_NOT_FOUND;
  383.         }
  384.     }
  385.     }
  386.     else {
  387.     pkt->dp_Res2 = ERROR_NO_FREE_STORE;
  388.     }
  389.  
  390.     return;
  391. }
  392.  
  393.  
  394. /*
  395.  *  FUNCTION
  396.  *    action_copy_lock
  397.  *
  398.  *  DESCRIPTION
  399.  *    Implement the DupLock function.
  400.  */
  401.  
  402. void
  403. action_copy_lock (register struct DosPacket * pkt)
  404. {
  405.     register struct myFileLock    * newlock;
  406.     register struct myFileLock    * oldlock;
  407.     register int          namelen;
  408.  
  409.     pkt->dp_Res1 = NULL;
  410.  
  411.     if (oldlock = (struct nyFileLock *)BTOC(pkt->dp_Arg1)) {
  412.  
  413.     if (newlock = (struct myFileLock *)AllocMem(sizeof(struct myFileLock),
  414.                         MEMF_PUBLIC | MEMF_CLEAR)) {
  415.         pkt->dp_Res1 = CTOB(newlock);
  416.  
  417.         newlock->fl_Access = oldlock->fl_Access;
  418.         newlock->fl_Task   = oldlock->fl_Task;
  419.         newlock->fl_Volume = oldlock->fl_Volume;
  420.  
  421.         if (oldlock->fl_Name) {
  422.         namelen = __builtin_strlen(oldlock->fl_Name);
  423.         if (newlock->fl_Name = DosAllocMem( namelen + 1 )) {
  424.             __builtin_memcpy (newlock->fl_Name, oldlock->fl_Name, namelen );
  425.         }
  426.         else {
  427.             pkt->dp_Res1 = NULL;
  428.             pkt->dp_Res2 = ERROR_NO_FREE_STORE;
  429.             FreeMem ((char *) newlock, sizeof(struct myFileLock));
  430.         }
  431.         }
  432.     }
  433.     else {
  434.         pkt->dp_Res2 = ERROR_NO_FREE_STORE;
  435.     }
  436.     }
  437.  
  438.     return;
  439. }
  440.  
  441.  
  442. /*
  443.  *  FUNCTION
  444.  *    action_freelock
  445.  *
  446.  *  DESCRIPTION
  447.  *    Frees the lock.
  448.  */
  449.  
  450. void
  451. action_freelock(register struct DosPacket * pkt)
  452. {
  453.     register struct myFileLock * lock;
  454.  
  455.     if (lock = BTOC(pkt->dp_Arg1)) {
  456.     if (lock->fl_Name) {
  457.         DosFreeMem((char *) lock->fl_Name);
  458.     }
  459.     FreeMem((char *)lock, sizeof(struct myFileLock));
  460.     }
  461.     pkt->dp_Res1 = DOS_TRUE;
  462.  
  463.     return;
  464. }
  465.  
  466.  
  467. /*
  468.  *  FUNCTION
  469.  *    action_delete
  470.  *
  471.  *  DESCRIPTION
  472.  *    Delete a MANX variable.
  473.  */
  474.  
  475. void
  476. action_delete(register struct DosPacket * pkt)
  477. {
  478.     char   name[NAMESIZE];
  479.     char * varname;
  480.  
  481.     BtoCStr(name, pkt->dp_Arg2, NAMESIZE-1);
  482.     varname = BaseName( name );
  483.  
  484.     if (* varname) {
  485.     if (Setenv(varname, NULL)) {
  486.         pkt->dp_Res1 = DOS_TRUE;
  487.     }
  488.     else {
  489.         /* As close at is can be. */
  490.         pkt->dp_Res2 = ERROR_OBJECT_NOT_FOUND;
  491.     }
  492.     }
  493.     else {
  494.     pkt->dp_Res2 = ERROR_BAD_STREAM_NAME;
  495.     }
  496.     return;
  497. }
  498.  
  499.  
  500. /*
  501.  *  FUNCTION
  502.  *    action_examine_object
  503.  *
  504.  *  DESCRIPTION
  505.  *    This function returns information about either ENV: itself
  506.  *    os a single varable. It fills in the FileInfoBlock with
  507.  *    appropriate values.
  508.  */
  509.  
  510. void
  511. action_examine_object(register struct DosPacket * pkt)
  512. {
  513.     register struct myFileLock      * lock;
  514.     register struct FileInfoBlock * fib;
  515.  
  516.     if (lock = (struct myFileLock *) BTOC(pkt->dp_Arg1)) {
  517.     if (fib = (struct FileInfoBlock *)BTOC(pkt->dp_Arg2)) {
  518.  
  519.         if (lock->fl_Name == NULL) {
  520.  
  521.         fib->fib_DiskKey    = FIRST_KEY;
  522.         fib->fib_DirEntryType   = 2;          /* Directory  */
  523.         fib->fib_EntryType    = 2;
  524.         fib->fib_Size        = 0;
  525.         fib->fib_NumBlocks    = 0;
  526.  
  527.         CtoBStr( "ENV", CTOB(fib->fib_FileName), 4);
  528.         }
  529.         else {
  530.         fib->fib_DiskKey    = FIRST_KEY;
  531.         fib->fib_DirEntryType    = -3;
  532.         fib->fib_EntryType    = -3;
  533.         Forbid();
  534.         fib->fib_Size        =
  535.                 __builtin_strlen(mygetenv(lock->fl_Name));
  536.         Permit();
  537.         fib->fib_NumBlocks    = 1;
  538.  
  539.         CtoBStr ( lock->fl_Name, CTOB(fib->fib_FileName), 30);
  540.         }
  541.  
  542.         fib->fib_Protection     = 0x00;          /* ----rwed   */
  543.         fib->fib_Comment[0]     = 0;
  544.         /* DateStamp( (long *) & fib->fib_Date );    /* Edit later! */
  545.  
  546.         pkt->dp_Res1 = DOS_TRUE;
  547.  
  548.     }
  549.     else {    /* No fib */
  550.         pkt->dp_Res2 = ERROR_OBJECT_WRONG_TYPE;
  551.     }
  552.     }
  553.     else {  /* No lock */
  554.     pkt->dp_Res2 = ERROR_INVALID_LOCK;
  555.     }
  556.     return;
  557. }
  558.  
  559.  
  560. /*
  561.  *  FUNCTION
  562.  *    action_examine_next
  563.  *
  564.  *  DESCTIPTION
  565.  *    This function:
  566.  *        - handles the `examine next' packet.
  567.  *        - is called as part of `examine object' funcetion.
  568.  *
  569.  *    It fills in the `FileInfoBlock' with appropriate values.
  570.  */
  571.  
  572. void
  573. action_examine_next (register struct DosPacket * pkt)
  574. {
  575.     register struct myFileLock      * lock;
  576.     register struct FileInfoBlock * fib;
  577.     register        char      * newname;
  578.     register        LONG        namelen;
  579.  
  580.     if (lock = (struct myFileLock *) BTOC(pkt->dp_Arg1)) {
  581.     if (fib = (struct FileInfoBlock *)BTOC(pkt->dp_Arg2)) {
  582.  
  583.         Forbid();
  584.  
  585.         if (newname = getnextenv(fib, pkt) ) {
  586.         for (namelen = 0; newname[namelen] != '='; namelen++)
  587.             ;
  588.  
  589.         fib->fib_DiskKey    += 1;
  590.         fib->fib_DirEntryType    = -3;
  591.         fib->fib_Protection    = 0x00;        /* ----rwed */
  592.         fib->fib_EntryType    = -3;
  593.         fib->fib_Size        =
  594.                 __builtin_strlen(newname) - namelen - 1;
  595.         fib->fib_NumBlocks    = 1;        
  596.         /* DateStamp( (long *) & fib->fib_Date );  /* Edit later! */
  597.         fib->fib_Comment[0]     = 0;
  598.  
  599.         __builtin_memcpy( fib->fib_FileName + 1, newname, namelen);
  600.         fib->fib_FileName[0] = namelen;
  601.  
  602.         pkt->dp_Res1 = DOS_TRUE;
  603.         }
  604.         Permit();
  605.     }
  606.     else {
  607.         pkt->dp_Res2 = ERROR_OBJECT_WRONG_TYPE;
  608.     }
  609.     }
  610.     else {
  611.     pkt->dp_Res2 = ERROR_INVALID_LOCK;
  612.     }
  613.     return;
  614. }
  615.  
  616.  
  617. /*
  618.  *  FUNCTION
  619.  *    mygetenv
  620.  *
  621.  *  DESCRIPTION
  622.  *    Get a MANX environment variable.
  623.  *    I can`t use the Arp function `getenv', because it will call
  624.  *    ENV: if the variable doesn`t exist in the MANX area, resulting
  625.  *    in a loop loop loop loop loop.....
  626.  *
  627.  *    The EnvSpace is builtup by strings in the form:
  628.  *         name=value
  629.  *    They are separated by one \0 and they are ended by two.
  630.  *
  631.  *  NOTE
  632.  *    The task MUST be Forbid()`ed before this function is called!
  633.  */
  634.  
  635. static char *
  636. mygetenv(register char * name)
  637. {
  638.     register char * p;
  639.     register int    len;
  640.  
  641.     if ( p = ((struct EnvBase*)ArpBase->EnvBase)->EnvSpace ) {
  642.  
  643.     len = __builtin_strlen(name);
  644.  
  645.     while (*p) {
  646.         if (Strncmp(p, name, len) == 0) {
  647.         if ( p[len] == '=' ) {
  648.             return (& p[len+1]);
  649.         }
  650.         }
  651.         p += __builtin_strlen(p) + 1;
  652.     }
  653.     }
  654.     return(NULL);
  655. }
  656.  
  657.  
  658. /*
  659.  *  FUNCTION
  660.  *    getnextenv
  661.  *
  662.  *  DESCRIPTION
  663.  *    Get the next environment variable. If an error accured the correct
  664.  *    errorcode is placed in pkt->dp_Res2 and a NULL is returned.
  665.  *
  666.  *  NOTE
  667.  *    This function MUST be called in Forbid()`ed state.
  668.  */
  669.  
  670. static char *
  671. getnextenv (register struct FileInfoBlock * fib, register struct DosPacket * pkt)
  672. {
  673.     register char * p;
  674.     register int    len;
  675.  
  676.     if ( p = ((struct EnvBase*)ArpBase->EnvBase)->EnvSpace ) {
  677.  
  678.     if (fib->fib_DirEntryType > 0) {
  679.         if (*p) {
  680.         return (p);
  681.         }
  682.         else {
  683.         pkt->dp_Res2 = ERROR_NO_MORE_ENTRIES;
  684.         return (NULL);
  685.         }
  686.     }
  687.  
  688.     while (*p) {
  689.         len = __builtin_strlen(p);
  690.  
  691.         if ( (Strncmp(p, fib->fib_FileName + 1,
  692.                 * fib->fib_FileName) == 0)
  693.             && (p[* fib->fib_FileName] == '=') ) {
  694.         
  695.         if ( * (p + len + 1) ) {
  696.             return (p + len + 1);
  697.         } 
  698.         else {
  699.             pkt->dp_Res2 = ERROR_NO_MORE_ENTRIES;
  700.             return (NULL);
  701.         }
  702.         }
  703.         p += len + 1;
  704.     }
  705.     pkt->dp_Res2 = ERROR_OBJECT_NOT_FOUND;    /* Correct??? */
  706.     }
  707.     return (NULL);    /* No environment at all, or entry not found */
  708. }
  709.  
  710.  
  711. /*
  712.  *  FUNCTION
  713.  *    getenvname
  714.  *
  715.  *  DESCRIPTION
  716.  *    Get the name of an environment variable.
  717.  *
  718.  *  NOTE
  719.  *    This function MUST be called in Forbid()`ed state!
  720.  */
  721.  
  722. static char *
  723. getenvname( register char * orgname )
  724. {
  725.     register char * p;
  726.     register int    len;
  727.     register char * newname;
  728.     register int    namelen;
  729.  
  730.     if ( p = ((struct EnvBase*)ArpBase->EnvBase)->EnvSpace ) {
  731.  
  732.     namelen = __builtin_strlen( orgname );
  733.  
  734.     while (*p) {
  735.         len = __builtin_strlen(p);
  736.  
  737.         if ( (Strncmp(p, orgname, namelen) == 0) &&
  738.             (p[namelen] == '=') ) {
  739.         newname = DosAllocMem (namelen+1);
  740.         __builtin_memcpy( newname, p, namelen );
  741.         return ( newname );
  742.         }
  743.         p += len + 1;
  744.     }
  745.     }
  746.     return (NULL);
  747. }
  748.  
  749.  
  750. /*
  751.  *  FUNCTION
  752.  *    ReAlloc
  753.  *
  754.  *  DESCRIPTION
  755.  *    Alloctes a biger memory area and copies the contens of
  756.  *    the original block. It then releases the original
  757.  *    block.
  758.  *
  759.  *  RETURNS
  760.  *    A pointer to the new memory block. Or a NULL is
  761.  *    AllocMem failed, in which case the original
  762.  *    memory block is NOT released.
  763.  */
  764.  
  765. static void *
  766. ReAlloc ( void * oldbuf, long oldsize, long newsize, long flags )
  767. {
  768.     void * newbuf;
  769.  
  770.     if (newbuf = AllocMem(newsize, flags)) {
  771.  
  772.     if ((oldbuf != NULL) && (oldsize != 0L)) {
  773.         __builtin_memcpy( newbuf, oldbuf, MAX(oldsize, newsize) );
  774.         FreeMem( oldbuf, oldsize );
  775.     }
  776.     }
  777.     return (newbuf);
  778. }
  779.